﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using YetAnotherChat.ChatCore.Models;
using YetAnotherChat.TcpServer;

namespace YetAnotherChat.TcpConsole
{
    internal class MessageBroadcaster
    {
        private MessageQueue _messageQueue = new MessageQueue();

        private OnlineSessionManager SessionManager;

        public MessageBroadcaster(WebSocketServer server)
        {
            SessionManager = new OnlineSessionManager(server);
            server.MessageReceived += new EventHandler<MessageEventArgs>(aServer_MessageReceived);
            server.MessgeSent += new EventHandler<MessageEventArgs>(aServer_MessgeSent);
        }

        void aServer_MessgeSent(object sender, MessageEventArgs e)
        {
            Debug.WriteLine("Sent data to :" + e.Connection.ClientAddress);
        }

        void aServer_MessageReceived(object sender, MessageEventArgs e)
        {
            Debug.WriteLine("Received Data From :" + e.Connection.ClientAddress);

            try
            {
                var json = e.Connection.Protocol.DataFrame.ToString();

                // <3 dynamics
                dynamic obj = JsonConvert.DeserializeObject(json);

                switch ((int)obj.Type)
                {
                    case (int)CommandType.Register:
                        SessionManager.Register(obj.Name.Value, (ServerConnection)e.Connection);
                        break;
                    case (int)CommandType.Message:
                        ChatMessage(obj.Message.Value, (ServerConnection)e.Connection, (bool) obj.FromAjaxWeb);
                        break;
                    case (int)CommandType.NameChange:
                        SessionManager.NameChange(obj.Name.Value, (ServerConnection)e.Connection);
                        break;
                }
            }
            catch (Exception ex) // Bad JSON! For shame.
            {
                var r = new Response { Type = ResponseType.Error, Data = new { ex.Message } };

                e.Connection.Send(JsonConvert.SerializeObject(r));
            }
        }

        /// <summary>
        /// Broadcasts a chat message to all online usrs
        /// </summary>
        /// <param name="message">The chat message to be broadcasted</param>
        /// <param name="context">The user's connection context</param>
        private void ChatMessage(string message, ServerConnection connection, bool fromAjaxWeb=false)
        {
            var u = SessionManager.GetUser(connection);

            var userName = u.User == null ? "temp" : u.User.DisplayName;

            var r = new Response { Type = ResponseType.Message, Data = new { userName, Message = message } };

            var userGuid = u.User == null ? Guid.NewGuid() : u.User.GuidId;

            if (!fromAjaxWeb)
            {
                _messageQueue.Add(new ChatMessage() { GuidId = Guid.NewGuid(), Text = message, UserGuidId = userGuid, Date = DateTime.UtcNow });
            }
            connection.Server.Broadcast(connection.ConnectionId, JsonConvert.SerializeObject(r));

        }

        /// <summary>
        /// Broadcasts an error message to the client who caused the error
        /// </summary>
        /// <param name="errorMessage">Details of the error</param>
        /// <param name="context">The user's connection context</param>
        public static void SendError(string errorMessage, Connection connection)
        {
            var r = new Response { Type = ResponseType.Error, Data = new { Message = errorMessage } };

            connection.Send(JsonConvert.SerializeObject(r));
        }
    }
}
